/*
 * Copyright 2008 Carnegie Mellon University
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *  
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, 
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package edu.cmu.lti.sepia.data.db;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import edu.cmu.lti.sepia.infra.eval.model.Pool;
import edu.cmu.lti.sepia.infra.eval.model.QAJudgmentUnit;
import edu.cmu.lti.sepia.infra.run.model.AnswerCandidate;
import edu.cmu.lti.sepia.infra.run.model.SelectionResultSet;

/**
 * 
 * Manages QA Judgment Unit object in a DB.
 * 
 * @see QAJudgmentUnit
 * @author Hideki Shima
 *
 */
public class QAJudgmentUnitDAO {
  
  //list of system responses to be evaluated
  public static List<QAJudgmentUnit> findJudgmentUnitsByTopicAndPool( SQL sql, String table, String topicId, int poolId )
  throws SQLException {
    String query = Query.generate( Query.FIND_QA_JUDGMENT_UNIT_BY_TOPIC_AND_POOL, table );
    PreparedStatement ps = sql.getConnection().prepareStatement(query);
    ps.setString(1, topicId);
    ps.setInt(2, poolId);
    ResultSet rs = null;
    List<QAJudgmentUnit> result = new ArrayList<QAJudgmentUnit>();
    
    rs = sql.executeSelect(ps);
    if ( rs == null ) System.out.println( ps );
    while ( rs.next() ) result.add( rsToObject(rs) );
    
    rs.close();
    ps.close();
    
    return result;
  }
  
  public static List<QAJudgmentUnit> findJudgmentUnitsByTopic( SQL sql, String table, String topicId )
  throws SQLException {
    String query = Query.generate( Query.FIND_QA_JUDGMENT_UNIT_BY_TOPIC, table );
    PreparedStatement ps = sql.getConnection().prepareStatement(query);
    ps.setString(1, topicId);
    ResultSet rs = null;
    List<QAJudgmentUnit> result = new ArrayList<QAJudgmentUnit>();
    
    rs = sql.executeSelect(ps);
    if ( rs == null ) System.out.println( ps );
    while ( rs.next() ) result.add( rsToObject(rs) );
    
    rs.close();
    ps.close();
    
    return result;
  }

  public static void storeUnits( SQL sql, String table, String poolName, SelectionResultSet answers ) 
  throws SQLException {
    // create pool
    // batch insert for each topic, 
    Pool pool = PoolDAO.addPool(sql, table, poolName, false);
    
    sql.getConnection().setAutoCommit(false);
    String query = Query.generate( Query.ADD_QA_JUDGMENT_UNIT, table );

    PreparedStatement ps = sql.getConnection().prepareStatement(query);
    List<String> externalIds = new ArrayList<String>( answers.keySet() );
    for ( int i=0; i<externalIds.size(); i++ ) {
      String externalId = externalIds.get(i);
      System.out.println("Topic "+externalId);
      //int internalTopicId = topics.get(i).getTopicId();
      int counter = 0;
      for ( AnswerCandidate ac : answers.get(externalId) ) {
        ps.setInt(1, pool.getPoolId());
        ps.setString(2, externalId);
        ps.setString(3, ac.getText());
        ps.addBatch();
        if (counter % 100 == 99) {
          ps.executeBatch();
          System.out.println("\tloaded "+(counter+1)+" documents");
        }
        counter++;
      }
      ps.executeBatch();
      System.out.println("\tloaded "+counter+" documents");
    }
    sql.getConnection().setAutoCommit(true);
    ps.close();
  }
  
  public static void deleteUnits( SQL sql, String table, int poolId ) throws SQLException {
    String query = Query.generate( Query.DELETE_QA_JUDGMENT_UNIT_BY_POOL_ID, table );
    PreparedStatement ps = sql.getConnection().prepareStatement(query);
    ps.setInt(1, poolId);
    sql.execute(ps);
    ps.close();
  }
  
  private static QAJudgmentUnit rsToObject( ResultSet rs ) {
    try {
      int judgmentId = rs.getInt(1);
      int poolId = rs.getInt(2);
      String topicId = rs.getString(3);
      String systemResponse = rs.getString(4);
      // order swaps!
      QAJudgmentUnit r = new QAJudgmentUnit( judgmentId, topicId, systemResponse, poolId, 0 );
      return r;
    } catch ( Exception e ) {
      e.printStackTrace();
      return null;
    }
  }
  
}
